/*
 * Copyright (C) 2012 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.demo.widget;

import java.util.ArrayList;
import java.util.List;

import android.app.LocalActivityManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;

/**
 * 针对于4.0之后使用Fragment的TabHost
 * @author Chaos	
 * @Description 针对于Fragment跳转的TabHost，不使用v4包中
 *              的FragmentTabHost，原因在于不知道为什么会导致渲染有问题。
 * @date 2012-12-18 
 */
public class TabHostICS extends TabHost implements OnTabChangeListener{
    
    private Context mContext;
    private FragmentManager mManager;
    private int mContentId;
    private TabInfo mLastTabInfo;
    private FragmentTransaction mTransaction;
    private AbsTabFragment mFragment;
    
    private OnTabChangeListener mOnTabChangeListener;
    
    private List<TabInfo> mTabsInfo = new ArrayList<TabInfo>();
    
    public TabHostICS(Context context) {
        super(context);
        init();
    }
    
    public TabHostICS(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    private void init() {
        super.setOnTabChangedListener(this);
    }
    
    @Override
    public final void setup() {
        throw new IllegalArgumentException("don't call this method,beacuse you must set contentView Id");
    }
    
    @SuppressWarnings("deprecation")
    @Override
    public final void setup(LocalActivityManager activityGroup) {
        throw new IllegalArgumentException("don't call this method,beacuse you must set contentView Id");
    }
    
    @Override
    public final void addTab(TabSpec tabSpec) {
        throw new IllegalArgumentException(
                "don't call this method,beacuse you must set target which is a Fragment");
    }
    
    @Override
    public void setOnTabChangedListener(OnTabChangeListener l) {
        this.mOnTabChangeListener = l;
    }
    
    public void setup(AbsTabFragment fragment,FragmentManager manager,int contentViewId){
        this.mFragment  = fragment;
        this.mContext   = fragment.getApplicationContext();
        this.mManager   = manager;
        this.mContentId = contentViewId;
        
        if(mContentId == 0){
            throw new IllegalArgumentException(
            "make sure contentViewId != 0");
        }
        
        super.setup();
    }
    
    /**
     * you must call this method to create a tab
     * @param tabSpec
     * @param fm
     * @param contentId
     */
    public void addTab(TabSpec tabSpec,Class<? extends Fragment> clazz,Bundle args){
        
        addTabCallback(true);
        
        tabSpec.setContent(new DummyTabFactory(mContext));
        
        TabInfo info = new TabInfo(tabSpec.getTag(), clazz, args);
        mTabsInfo.add(info);
        
        super.addTab(tabSpec);
        
        addTabCallback(false);
    }
    
    /**
     * 创建一个空的View用来填充TabContent
     * @author Chaos	
     * @date 2012-12-18
     */
    static class DummyTabFactory implements TabHost.TabContentFactory {
        private final Context mContext;

        public DummyTabFactory(Context context) {
            mContext = context;
        }

        @Override
        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }
    
    /**
     * TabInfo
     * @author Chaos	
     * @date 2012-12-18
     */
    static final class TabInfo {
        private final String tag;
        private final Class<?> clss;
        private final Bundle args;
        private Fragment fragment;

        TabInfo(String _tag, Class<?> _class, Bundle _args) {
            tag = _tag;
            clss = _class;
            args = _args;
        }
    }
    
    @Override
    public void onTabChanged(String tabId) {
        doTabChangeFragment(tabId);
        
        mOnTabChangeListener.onTabChanged(tabId);
    }
    
    public void doTabChangeFragment(String tabId) {
        
        final int count = mTabsInfo.size();
        TabInfo newTabInfo = null;

        for (int i = 0; i < count; i++) {
            TabInfo info = mTabsInfo.get(i);
            if (info.tag.equals(tabId)) {
                newTabInfo = info;
            }
        }

        if (mLastTabInfo == newTabInfo) {
            return;
        }
        
        mTransaction = mManager.beginTransaction();
        
        if (mLastTabInfo != null && mLastTabInfo.fragment != null) {
            mTransaction.remove(mLastTabInfo.fragment);
        }
        
        newTabInfo.fragment = Fragment.instantiate(mContext, newTabInfo.clss.getName(),
                newTabInfo.args);
//        newTabInfo.fragment.setTargetFragment(mFragment, getCurrentTab());
        
        mTransaction.add(mContentId, newTabInfo.fragment, newTabInfo.tag);
        
        mLastTabInfo = newTabInfo;
        mTransaction.commit();
    }
    
    private AddTabCallback mAddTabCallback;
    
    public void setAddTabCallback(AddTabCallback callback){
        this.mAddTabCallback = callback;
    }
    
    private void addTabCallback(boolean before){
        if(mAddTabCallback == null){
            return ;
        }
        if(before){
            mAddTabCallback.addTabBefore(this);
        }else{
            mAddTabCallback.addTabAfter(this);
        }
    }
    
    public static interface AddTabCallback{
        public void addTabBefore(TabHostICS tabHost); 
        public void addTabAfter(TabHostICS tabHost);
    }
}
